/*
 * Funciones relacionas con la ropa y su relación con los jugadores
 */

package com.bitoon.basketdudes.ws;

import com.bitoon.basketdudes.jpa.*;
import java.util.*;
import javax.naming.*;
import javax.persistence.*;

import javax.servlet.http.*;
import org.apache.log4j.*;
import org.jdom.*;


/**
 * @author PacoFELC
 * 23/11/2011 - Creación de la clase para aligerar DatosEquipo
 */
public class Vestidor {

    Context     initContext = null;
    Context     envContext  = null;
    Logger      log         = Logger.getLogger(DatosEquipo.class);

    private int calcularRopaJugadorId ( EntityManager em, int p_jugador_id ) throws ExcepcionGeneral {
        Query q_recalcula = em.createNamedQuery("Jugador.findById");
        q_recalcula.setParameter("id" , p_jugador_id );
        Jugador cambiar = (Jugador)q_recalcula.getSingleResult();

log.debug( "VAMOS A RECALCULAR JUGADOR " + cambiar.getId() );

        return calcularRopaJugador ( em, cambiar );
    }

    public int calcularRopaJugador (EntityManager em, Jugador p_jugador) throws ExcepcionGeneral {
        int error=0;
        Date hoy = new Date();

        /* Buscamos la ropa que había */
        Query qr = em.createNamedQuery("RopaJugador.findByJugadorId");
        qr.setParameter("jugadorId", p_jugador.getId());

        List<RopaJugador> lista_ropa = qr.getResultList();

log.debug("[TRAZA][RestetRopa]:" );
        p_jugador.ResetRopa();

        /* Comprobamos si la ropa afecta a las características del jugador */
        for ( int i=0;i< lista_ropa.size(); i++) {
            Ropa        ropa         = lista_ropa.get(i).getRopa();
            RopaJugador ropa_jugador = lista_ropa.get(i);
log.debug("[TRAZA][CalcularRopa]:"+i );
log.debug("[TRAZA][jugador]:"+p_jugador.getId() );

            // Si tiene ropa con fecha de caducidad que ha caducado
            // la marcamos a 0 milisg 01/01/1970 para saber que no hay que recalcular
            // las propiedades
            /* LO COMENTAMOS PORQUE PARECE INNECESARIO
            if ( ropa_jugador.getFCaduca()!= null && ropa_jugador.getFCaduca().compareTo(hoy)<0 ) {
                log.debug("[TRAZA][CADUCADA SIN MARCAR]:"+ ropa_jugador.getFCaduca() );
                ropa_jugador.setFCaduca( new java.sql.Date(0) );
                em.persist(ropa_jugador);
            }
             */

            // Si en el slot hay ropa
            // y los usos no son 0
            // y la fecha de caducidad no existe o si tiene valor es > que la fecha actual.
            if ( ropa != null && ropa_jugador.getUsos()!=0
                && (ropa_jugador.getFCaduca()==null || ropa_jugador.getFCaduca().compareTo(hoy)>0)
            ) {
                log.debug("[TRAZA][ropa]:"+ ropa.getId());
                if ( ropa.getProp1()!= null && ropa.getProp1()!= 0  )
                    modificaRopaJugador ( ropa.getProp1(), ropa.getModif1(), ropa.getValor1(), p_jugador );
                if ( ropa.getProp2()!= null && ropa.getProp2()!= 0 )
                    modificaRopaJugador ( ropa.getProp2(), ropa.getModif2(), ropa.getValor2(), p_jugador );
                if ( ropa.getProp3()!= null && ropa.getProp3()!= 0 )
                    modificaRopaJugador ( ropa.getProp3(), ropa.getModif3(), ropa.getValor3(), p_jugador );
                if ( ropa.getProp4()!= null && ropa.getProp4()!= 0 )
                    modificaRopaJugador ( ropa.getProp4(), ropa.getModif4(), ropa.getValor4(), p_jugador );
            } else {
                if ( ropa != null )
                    log.debug("[TRAZA] usos==0 o caducada " + ropa_jugador.getUsos() + " fecha " + ropa_jugador.getFCaduca() );
            }
        }

        return error;
    }

    private int modificaRopaJugador ( int p_indice, short p_modificador, short p_valor, Jugador p_jugador ) throws ExcepcionGeneral  {
log.debug("[TRAZA][modificaRopaJugador]:"+ p_indice + " modif " + p_modificador);
        switch ( p_indice ) {
            case 1: /* TIRO 2 */
                p_jugador.setT2             ( asignaPropiedad ( p_jugador.getT2           (),p_modificador,p_valor,p_jugador.getBT2             ()) );
                break;
            case 2: /* TIRO 3 */
                p_jugador.setT3             ( asignaPropiedad ( p_jugador.getT3           (),p_modificador,p_valor,p_jugador.getBT3             ()) );
                break;
            case 3: /* TIRO LIBRE */
                p_jugador.setT1             ( asignaPropiedad ( p_jugador.getT1           (),p_modificador,p_valor,p_jugador.getBT1             ()) );
                break;
            case 4: /* AGRESIVIDAD */
                p_jugador.setAgresividad    ( asignaPropiedad ( p_jugador.getAgresividad  (),p_modificador,p_valor,p_jugador.getBAgresividad    ()) );
                break;
            case 5: /* DRIBLIN */
                p_jugador.setDriblin        ( asignaPropiedad ( p_jugador.getDriblin      (),p_modificador,p_valor,p_jugador.getBDriblin        ()) );
                break;
            case 6: /* PASE */
                p_jugador.setPase           ( asignaPropiedad ( p_jugador.getPase         (),p_modificador,p_valor,p_jugador.getBPase           ()) );
                break;
            case 7: /* REBOTE ATAQUE */
                p_jugador.setReboteAtaque   ( asignaPropiedad ( p_jugador.getReboteAtaque (),p_modificador,p_valor,p_jugador.getBReboteAtaque   ()) );
                break;
            case 8: /* REBOTE DEFENSA */
                p_jugador.setReboteDefensa  ( asignaPropiedad ( p_jugador.getReboteDefensa(),p_modificador,p_valor,p_jugador.getBReboteDefensa  ()) );
                break;
            case 9: /* ROBO */
                p_jugador.setRobo           ( asignaPropiedad ( p_jugador.getRobo         (),p_modificador,p_valor,p_jugador.getBRobo           ()) );
                break;
            case 10: /* TAPON */
                p_jugador.setTapon          ( asignaPropiedad ( p_jugador.getTapon        (),p_modificador,p_valor,p_jugador.getBTapon          ()) );
                break;
            case 11: /* DEFENSA */
                p_jugador.setDefensa        ( asignaPropiedad ( p_jugador.getDefensa      (),p_modificador,p_valor,p_jugador.getBDefensa        ()) );
                break;
            case 12: /* RESISTENCIA */
                p_jugador.setResistencia    ( asignaPropiedad ( p_jugador.getResistencia  (),p_modificador,p_valor,p_jugador.getBResistencia    ()) );
                break;
            case 13: /* VELOCIDAD */
                p_jugador.setVelocidad      ( asignaPropiedad ( p_jugador.getVelocidad    (),p_modificador,p_valor,p_jugador.getBVelocidad      ()) );
                break;
            case 14: /* SPRINT */
                p_jugador.setSprint         ( asignaPropiedad ( p_jugador.getSprint       (),p_modificador,p_valor,p_jugador.getBSprint         ()) );
                break;
            case 15: /* TEAMWORK */
                p_jugador.setTeamwork       ( asignaPropiedad ( p_jugador.getTeamwork     (),p_modificador,p_valor,p_jugador.getBTeamwork       ()) );
                break;

            case 50: //todas
                p_jugador.setT1             ( asignaPropiedad ( p_jugador.getT1           (),p_modificador,p_valor,p_jugador.getBT1             ()) );
                p_jugador.setT2             ( asignaPropiedad ( p_jugador.getT2           (),p_modificador,p_valor,p_jugador.getBT2             ()) );
                p_jugador.setT3             ( asignaPropiedad ( p_jugador.getT3           (),p_modificador,p_valor,p_jugador.getBT3             ()) );
                p_jugador.setAgresividad    ( asignaPropiedad ( p_jugador.getAgresividad  (),p_modificador,p_valor,p_jugador.getBAgresividad    ()) );
                p_jugador.setDriblin        ( asignaPropiedad ( p_jugador.getDriblin      (),p_modificador,p_valor,p_jugador.getBDriblin        ()) );
                p_jugador.setReboteAtaque   ( asignaPropiedad ( p_jugador.getReboteAtaque (),p_modificador,p_valor,p_jugador.getBReboteAtaque   ()) );
                p_jugador.setPase           ( asignaPropiedad ( p_jugador.getPase         (),p_modificador,p_valor,p_jugador.getBPase           ()) );
                p_jugador.setDefensa        ( asignaPropiedad ( p_jugador.getDefensa      (),p_modificador,p_valor,p_jugador.getBDefensa        ()) );
                p_jugador.setRobo           ( asignaPropiedad ( p_jugador.getRobo         (),p_modificador,p_valor,p_jugador.getBRobo           ()) );
                p_jugador.setTapon          ( asignaPropiedad ( p_jugador.getTapon        (),p_modificador,p_valor,p_jugador.getBTapon          ()) );
                p_jugador.setReboteDefensa  ( asignaPropiedad ( p_jugador.getReboteDefensa(),p_modificador,p_valor,p_jugador.getBReboteDefensa  ()) );
                p_jugador.setResistencia    ( asignaPropiedad ( p_jugador.getResistencia  (),p_modificador,p_valor,p_jugador.getBResistencia    ()) );
                p_jugador.setVelocidad      ( asignaPropiedad ( p_jugador.getVelocidad    (),p_modificador,p_valor,p_jugador.getBVelocidad      ()) );
                p_jugador.setTeamwork       ( asignaPropiedad ( p_jugador.getTeamwork     (),p_modificador,p_valor,p_jugador.getBTeamwork       ()) );
                p_jugador.setSprint         ( asignaPropiedad ( p_jugador.getSprint       (),p_modificador,p_valor,p_jugador.getBSprint         ()) );
                break;
            case 51: // tiro
                p_jugador.setT1             ( asignaPropiedad ( p_jugador.getT1           (),p_modificador,p_valor,p_jugador.getBT1             ()) );
                p_jugador.setT2             ( asignaPropiedad ( p_jugador.getT2           (),p_modificador,p_valor,p_jugador.getBT2             ()) );
                p_jugador.setT3             ( asignaPropiedad ( p_jugador.getT3           (),p_modificador,p_valor,p_jugador.getBT3             ()) );
                break;
            case 52: // ofensivas
                p_jugador.setAgresividad    ( asignaPropiedad ( p_jugador.getAgresividad  (),p_modificador,p_valor,p_jugador.getBAgresividad    ()) );
                p_jugador.setDriblin        ( asignaPropiedad ( p_jugador.getDriblin      (),p_modificador,p_valor,p_jugador.getBDriblin        ()) );
                p_jugador.setReboteAtaque   ( asignaPropiedad ( p_jugador.getReboteAtaque (),p_modificador,p_valor,p_jugador.getBReboteAtaque   ()) );
                p_jugador.setPase           ( asignaPropiedad ( p_jugador.getPase         (),p_modificador,p_valor,p_jugador.getBPase           ()) );
                break;
            case 53: // defensivas
                p_jugador.setDefensa        ( asignaPropiedad ( p_jugador.getDefensa      (),p_modificador,p_valor,p_jugador.getBDefensa        ()) );
                p_jugador.setRobo           ( asignaPropiedad ( p_jugador.getRobo         (),p_modificador,p_valor,p_jugador.getBRobo           ()) );
                p_jugador.setTapon          ( asignaPropiedad ( p_jugador.getTapon        (),p_modificador,p_valor,p_jugador.getBTapon          ()) );
                p_jugador.setReboteDefensa  ( asignaPropiedad ( p_jugador.getReboteDefensa(),p_modificador,p_valor,p_jugador.getBReboteDefensa  ()) );
                break;
            case 54: // generales
                p_jugador.setResistencia    ( asignaPropiedad ( p_jugador.getResistencia  (),p_modificador,p_valor,p_jugador.getBResistencia    ()) );
                p_jugador.setVelocidad      ( asignaPropiedad ( p_jugador.getVelocidad    (),p_modificador,p_valor,p_jugador.getBVelocidad      ()) );
                p_jugador.setTeamwork       ( asignaPropiedad ( p_jugador.getTeamwork     (),p_modificador,p_valor,p_jugador.getBTeamwork       ()) );
                p_jugador.setSprint         ( asignaPropiedad ( p_jugador.getSprint       (),p_modificador,p_valor,p_jugador.getBSprint         ()) );
                break;
            case 55: // todas menos generales
                p_jugador.setT1             ( asignaPropiedad ( p_jugador.getT1           (),p_modificador,p_valor,p_jugador.getBT1             ()) );
                p_jugador.setT2             ( asignaPropiedad ( p_jugador.getT2           (),p_modificador,p_valor,p_jugador.getBT2             ()) );
                p_jugador.setT3             ( asignaPropiedad ( p_jugador.getT3           (),p_modificador,p_valor,p_jugador.getBT3             ()) );
                p_jugador.setAgresividad    ( asignaPropiedad ( p_jugador.getAgresividad  (),p_modificador,p_valor,p_jugador.getBAgresividad    ()) );
                p_jugador.setDriblin        ( asignaPropiedad ( p_jugador.getDriblin      (),p_modificador,p_valor,p_jugador.getBDriblin        ()) );
                p_jugador.setReboteAtaque   ( asignaPropiedad ( p_jugador.getReboteAtaque (),p_modificador,p_valor,p_jugador.getBReboteAtaque   ()) );
                p_jugador.setPase           ( asignaPropiedad ( p_jugador.getPase         (),p_modificador,p_valor,p_jugador.getBPase           ()) );
                p_jugador.setDefensa        ( asignaPropiedad ( p_jugador.getDefensa      (),p_modificador,p_valor,p_jugador.getBDefensa        ()) );
                p_jugador.setRobo           ( asignaPropiedad ( p_jugador.getRobo         (),p_modificador,p_valor,p_jugador.getBRobo           ()) );
                p_jugador.setTapon          ( asignaPropiedad ( p_jugador.getTapon        (),p_modificador,p_valor,p_jugador.getBTapon          ()) );
                p_jugador.setReboteDefensa  ( asignaPropiedad ( p_jugador.getReboteDefensa(),p_modificador,p_valor,p_jugador.getBReboteDefensa  ()) );
            case 70: // La más baja
                modificaRopaJugador ( BuscarOrden( -1, p_jugador ), p_modificador, p_valor, p_jugador );
                break;
            case 71: // Las dos más bajas
                modificaRopaJugador ( BuscarOrden( -1, p_jugador), p_modificador, p_valor, p_jugador );
                modificaRopaJugador ( BuscarOrden( -2, p_jugador), p_modificador, p_valor, p_jugador );
                break;
            case 72: // Las tres más bajas
                modificaRopaJugador ( BuscarOrden( -1, p_jugador ), p_modificador, p_valor, p_jugador );
                modificaRopaJugador ( BuscarOrden( -2, p_jugador ), p_modificador, p_valor, p_jugador );
                modificaRopaJugador ( BuscarOrden( -3, p_jugador ), p_modificador, p_valor, p_jugador );
                break;
            case 73: // Las cuatro más bajas
                modificaRopaJugador ( BuscarOrden( -1, p_jugador ), p_modificador, p_valor, p_jugador );
                modificaRopaJugador ( BuscarOrden( -2, p_jugador ), p_modificador, p_valor, p_jugador );
                modificaRopaJugador ( BuscarOrden( -3, p_jugador ), p_modificador, p_valor, p_jugador );
                modificaRopaJugador ( BuscarOrden( -4, p_jugador ), p_modificador, p_valor, p_jugador );
                break;
            case 80: // La más alta
                modificaRopaJugador ( BuscarOrden( 1, p_jugador ), p_modificador, p_valor, p_jugador );
                break;
            case 81: // Las dos más altas
                modificaRopaJugador ( BuscarOrden( 1, p_jugador ), p_modificador, p_valor, p_jugador );
                modificaRopaJugador ( BuscarOrden( 2, p_jugador ), p_modificador, p_valor, p_jugador );
                break;
            default:
                break;
        }
        return 0;
    }

    private int BuscarOrden ( int p_cual, Jugador p_jugador) {

log.debug("BUSCARORDEN "+p_cual);
        ArrayList <Caracteristica> lista = new ArrayList <Caracteristica>(15) ;

        lista.add(new Caracteristica( p_jugador.getBT2           (), 1) );
        lista.add(new Caracteristica( p_jugador.getBT3           (), 2) );
        lista.add(new Caracteristica( p_jugador.getBT1           (), 3) );
        lista.add(new Caracteristica( p_jugador.getBAgresividad  (), 4) );
        lista.add(new Caracteristica( p_jugador.getBDriblin      (), 5) );
        lista.add(new Caracteristica( p_jugador.getBPase         (), 6) );
        lista.add(new Caracteristica( p_jugador.getBReboteAtaque (), 7) );
        lista.add(new Caracteristica( p_jugador.getBReboteDefensa(), 8) );
        lista.add(new Caracteristica( p_jugador.getBRobo         (), 9) );
        lista.add(new Caracteristica( p_jugador.getBTapon        (),10) );
        lista.add(new Caracteristica( p_jugador.getBDefensa      (),11) );
        lista.add(new Caracteristica( p_jugador.getBResistencia  (),12) );
        lista.add(new Caracteristica( p_jugador.getBVelocidad    (),13) );
        lista.add(new Caracteristica( p_jugador.getBSprint       (),14) );
        lista.add(new Caracteristica( p_jugador.getBTeamwork     (),15) );

        Collections.sort ( lista );

log.debug("0  "+lista.get(0).propiedad+" "+lista.get(0).valor);
log.debug("1  "+lista.get(1).propiedad+" "+lista.get(1).valor);
log.debug("2  "+lista.get(2).propiedad+" "+lista.get(2).valor);
log.debug("3  "+lista.get(3).propiedad+" "+lista.get(3).valor);
log.debug("4  "+lista.get(4).propiedad+" "+lista.get(4).valor);
log.debug("5  "+lista.get(5).propiedad+" "+lista.get(5).valor);
log.debug("9  "+lista.get(9).propiedad+" "+lista.get(9).valor);
log.debug("10 "+lista.get(10).propiedad+" "+lista.get(10).valor);
log.debug("11 "+lista.get(11).propiedad+" "+lista.get(11).valor);
log.debug("12 "+lista.get(12).propiedad+" "+lista.get(12).valor);
log.debug("13 "+lista.get(13).propiedad+" "+lista.get(13).valor);
log.debug("14 "+lista.get(14).propiedad+" "+lista.get(14).valor);

        if ( p_cual > 0 ) {
log.debug("LA MAYOR " + p_cual + " " + lista.get(lista.size()-(p_cual) ).propiedad);
            // (positivo) Busca de las ultimas
            return lista.get(lista.size()-(p_cual)).propiedad;
        } else {
log.debug("LA MENOR " + p_cual + " " + lista.get(-(p_cual+1)).propiedad);
            // (negativo) Busca de las últimas
            return lista.get(-(p_cual+1)).propiedad;
        }
    }

    private short asignaPropiedad ( short ant_valor, short p_modificador, short p_valor, short p_valor_propiedad ) throws ExcepcionGeneral  {
log.debug("[TRAZA][modificaRopaJugador]:"+ ant_valor + " modif: " + p_modificador + " valor:" + p_valor +" propiedad:" + p_valor_propiedad);
        switch ( p_modificador) {
            case 1: //sumar
log.debug("[TRAZA][sumar]:"+ (short) (ant_valor + p_valor) );
                return (short) (ant_valor + p_valor);
            case 2: //restar
log.debug("[TRAZA][restar]:"+ (short) (ant_valor - p_valor) );
                return (short) (ant_valor - p_valor);
            case 3: // sumar porcentaje
log.debug("[TRAZA][%]:"+ (short)(ant_valor + (Math.round(  (p_valor_propiedad * (p_valor / 100.0f) ))))) ;
                return (short)(ant_valor + (Math.round(  (p_valor_propiedad * (p_valor / 100.0f) )))) ;
            case 4: // restar porcentaje
log.debug("[TRAZA][-%]:"+ (short)(ant_valor - (Math.round(  (p_valor_propiedad * (p_valor / 100.0f) ))))) ;
                return (short)(ant_valor + (-Math.round(  (p_valor_propiedad * (p_valor / 100.0f) )))) ;
            default:
                throw new ExcepcionGeneral( -9, "Modificador desconocido"  );
        }
    }

    public void calcularPowerPlay( EntityManager em, Equipo p_equipo) {
        java.lang.Float powerplay=0.0f;
        Query q = em.createNamedQuery("Jugador.findByPowerPlay");
        q.setParameter("equipo", p_equipo.getId());

        List<Jugador> lista = q.getResultList();
        Jugador jugador = null;

        int cuantos = lista.size();

        for ( int i=0;i< cuantos && i<5 ; i ++ ){
            jugador = lista.get(i);
            powerplay = powerplay + jugador.getNivel();
        }

        if ( p_equipo.getPowerplay() != powerplay) {
            log.debug(" NUEVO POWERPLAY----" + p_equipo.getPowerplay() + " --> " + powerplay);
            p_equipo.setPowerplay(powerplay);
        }
    }
    
    /* Buscamos toda la ropa que tiene usos que gastar y los decrementamos */
    void ConsumirUsosRopa ( EntityManager em, Equipo p_equipo ) throws ExcepcionGeneral{
        Query q = em.createNamedQuery("RopaJugador.findUsosByEquipoId");
        q.setParameter("equipoId" , p_equipo.getId() );

        List<RopaJugador> lista = q.getResultList();
        RopaJugador       ropa_jugador=null;

        int cuantos = lista.size();
        int jugador_recalcular=0;
        for ( int i=0;i<cuantos; i ++ ){
            ropa_jugador = lista.get(i);
log.debug( "----------------" + ropa_jugador.getRopa().getNombre() );
log.debug( "USOS " + ropa_jugador.getUsos() );
            if ( jugador_recalcular != 0 &&
                 jugador_recalcular != ropa_jugador.getRopaJugadorPK().getJugadorId()) {
                // Si detectamos un jugador con ropa sin usos, recalculamos sus características
                calcularRopaJugadorId ( em, jugador_recalcular );
                jugador_recalcular=0;
            }

            if ( ropa_jugador.getUsos()>0 ) {
                ropa_jugador.setUsos( ropa_jugador.getUsos()-1 );
                if ( ropa_jugador.getUsos() == 0 ) {
                    jugador_recalcular=lista.get(0).getRopaJugadorPK().getJugadorId();
log.debug( "ALGO AGOTADO slot " + ropa_jugador.getRopaJugadorPK().getSlot()+ " jugador " + ropa_jugador.getRopaJugadorPK().getJugadorId() );
                }
            }
        }
        if ( jugador_recalcular != 0 ) {
            calcularRopaJugadorId ( em, jugador_recalcular );
        }
    }


    public int comprobarInstanciasRopaCaducada( EntityManager p_em, Equipo p_equipo ) throws ExcepcionGeneral {

        Date hoy = new Date();
        int  jugadores_caducados=0;

        Query q = p_em.createNamedQuery("RopaInstancia.findEquipados");
        q.setParameter("equipo_id" , p_equipo.getId() );

        List<RopaInstancia> lista = q.getResultList();
        RopaInstancia       ropa_instancia=null;

        int jugador_recalcular=0;
        int cuantos = lista.size();
        for ( int i=0;i<cuantos; i ++ ){
            ropa_instancia=lista.get(i);

            if ( jugador_recalcular != 0 &&
                 jugador_recalcular != ropa_instancia.getJugadorId().getId() ) {
                // Si detectamos un jugador con ropa sin usos, recalculamos sus características
                calcularRopaJugadorId ( p_em, jugador_recalcular );
                jugador_recalcular=0;
log.debug( "¨¨¨CADUCADO jugador " + ropa_instancia.getJugadorId().getId() );
                jugadores_caducados++;
            }

            if ( ropa_instancia.getFCaduca().compareTo(hoy)<0 &&
                 ropa_instancia.getFCaduca().getTime()>86400000
                 ) {
                    jugador_recalcular=ropa_instancia.getJugadorId().getId();
log.debug( "¨¨¨CADUCADA ropa " + ropa_instancia.getFCaduca().getTime() + " jugador " + ropa_instancia.getJugadorId().getId() + " isntancia " + ropa_instancia.getId() );
            }
        }

        if ( jugador_recalcular != 0 ) {
            // Si detectamos un jugador con ropa sin usos, recalculamos sus características
            calcularRopaJugadorId ( p_em, jugador_recalcular );
log.debug( "¨¨¨CADUCADO jugador " + ropa_instancia.getJugadorId().getId() );
            jugadores_caducados++;
        }


        return jugadores_caducados;
    }





/*
    private RopaJugadorPK AsignarSlot( int p_jugador_id_buscar, short p_slot) {

        RopaJugadorPK pk_ropajugador = new RopaJugadorPK();
        pk_ropajugador.setJugadorId (p_jugador_id_buscar);
        pk_ropajugador.setSlot    ((short)p_slot);
        return pk_ropajugador;
    }
*/
    // Mete una ropa en el armario del equipo
    public int meterArmario ( EntityManager em, int p_equipo_id, int p_ropa_id) throws ExcepcionGeneral
    {
        int error=0;

         log.debug("[TRAZA][MeterArmario]:1");
        ArmarioEquipo   armario_quitar;
        ArmarioEquipoPK armario_quitar_pk;
        /* Añadimos la ropa al armario del equipo*/
        Query q3 = em.createNamedQuery("ArmarioEquipo.findByEquipoIdRopaId");
        q3.setParameter("equipoId", p_equipo_id);
        q3.setParameter("ropaId", p_ropa_id);

        List<ArmarioEquipo> lista_armario = q3.getResultList();
        if (lista_armario.isEmpty()) {
            /* Inserto Armario */
            armario_quitar_pk = new ArmarioEquipoPK();
            armario_quitar_pk.setEquipoId(p_equipo_id);
            armario_quitar_pk.setRopaId(p_ropa_id);

            armario_quitar = new ArmarioEquipo();
            armario_quitar.setCantidad((short)1);
            armario_quitar.setArmarioEquipoPK(armario_quitar_pk);

            em.persist(armario_quitar);
        } else {
            /* Actualizo Armario */
            armario_quitar = lista_armario.get(0);
            short cantidad = armario_quitar.getCantidad();
            cantidad += (short) 1;
            armario_quitar.setCantidad(cantidad);
        }

        return error;
    }
    // Saca una ropa del armario del equipo
    private int sacarArmario ( EntityManager em, int p_equipo_id, Ropa p_ropa) throws ExcepcionGeneral
    {
        int error=0;

        ArmarioEquipo armario_quitar;
        ArmarioEquipoPK armario_quitar_pk;
        /* Añadimos la ropa al armario del equipo*/
        Query q3 = em.createNamedQuery("ArmarioEquipo.findByEquipoIdRopaId");
        q3.setParameter("equipoId", p_equipo_id);
        q3.setParameter("ropaId", p_ropa.getId());

        List<ArmarioEquipo> lista_armario = q3.getResultList();
        if (lista_armario.isEmpty()) {
            throw new ExcepcionGeneral( -8, "Ropa no existe en Armario" + p_ropa.getId() );
        } else {
log.debug("[TRAZA][SACARARMARIO]:" + p_ropa.getId() );

            // Actualizo Armario
            armario_quitar = lista_armario.get(0);
            short cantidad = armario_quitar.getCantidad();
            cantidad -= (short) 1;

log.debug("[TRAZA][CANTIDAD]:" + cantidad );

            if (cantidad == 0)
                em.remove(armario_quitar);
            else
                armario_quitar.setCantidad(cantidad);
        }
        return error;
    }



    /*
        vestirJugador:
            p_jugador - recibe el jugador sobre el que queremos actuar
            p_tabla   - una hashtable como clave el slot que queremos modificar
                        y como contenido el identificador de ropa ( 0 - queremos quitar la ropa de ese slot,
                        -1 - no queremos hacer nada sobre el slot,
                        negativo pero menor de -1 queremos ponernos una INSTANCIA de ropa
                        otro - queremos poner esa ropa en el slot.
            p_tipo_operacion - 0 operacion normal vestir/desvestir, 1 venta de jugador, 2 carta quitar tatuaje
     *
     *      Esta función viste, sacando la nueva ropa del armario del equipo, y metiendo la vieja ropa en el
     *      armario del equipo.
     *
     *      También quita la ropa del slot si el identificador de ropa pasado es 0, y metiendo la ropa quitada
     *      en el armario del equipo.
     *
     *      Las caracteristicas del jugador son recalculadas en base a la ropa que al final le queda puesta.
     *
     *      Retorno:
     *          -2,  "Jugador no Existe"
     *          -3,  "Ropa a quitar no Existe"
     *          -4,  "Ropa a poner no Existe"
     *
     *          -8,  "Ropa no existe en Armario"
     *          -9,  "Modificador desconocido"
     *          -14, "Slot no adecuado"
     *          -15, "El tatuaje se quita con una carta"
     *          -16, "No tienes carta de quitar tatuaje"
     *          -17, "Instancia no encontrada"
     *          -18, "Instancia ya en uso"
     */
    public String vestirJugador ( EntityManager em, int p_jugador_id, Hashtable p_tabla, int  p_tipo_operacion) throws ExcepcionGeneral{
        String          retorno;
        //EntityManager   em      = null;
        Jugador         jugador = null;
        int             error   = 0;
        //Integer         p_ropa_id=0;
        Boolean         guardar_armario=true;
        Boolean         hacer_commit=false;

        try {
            if ( em.getTransaction().isActive()==false  ) {
                em.getTransaction().begin();
                hacer_commit = true;
            }
            RopaJugadorPK   pk_ropajugador      = null;

            Query q = em.createNamedQuery("Jugador.findById");
            q.setParameter("id", p_jugador_id);

            List<Jugador> lista_jugador = q.getResultList();

            if (lista_jugador.isEmpty()) {
                log.error("[TRAZA][Jugador no existe]: " + p_jugador_id);
                throw new ExcepcionGeneral( -2, "Jugador no existe" + p_jugador_id );
            } else {
                jugador = lista_jugador.get(0);
                log.debug("[TRAZA][ENCONTRADO]: " + p_jugador_id);
            }

            Query q1 = em.createNamedQuery("RopaJugador.findByJugadorId");
            q1.setParameter("jugadorId", p_jugador_id);

            List<RopaJugador> lista = q1.getResultList();

            if ( lista.size()>0 && lista.size()<7) {
                throw new ExcepcionGeneral( -99, "Slots INCORRECTOS" + lista.size()  );
            }

for (short i=1; i< 8;i ++) {
    log.debug("[TRAZA][TABLA ROPA PONER]:" + (Integer)p_tabla.get(i) );
}

            if (lista.size()==0 ) {
                /* Si está vacía creo los slots vacios*/
                for ( short p_slot=1;p_slot<=7;p_slot++ ) {
                    RopaJugador nueva_ropa = new RopaJugador();
                    nueva_ropa.setRopa(null);
                    RopaJugadorPK nueva_ropa_pk = new RopaJugadorPK ();
                    nueva_ropa_pk.setSlot(p_slot);
                    nueva_ropa_pk.setJugadorId(p_jugador_id);

                    nueva_ropa.setRopaJugadorPK(nueva_ropa_pk);

log.debug("[CREO SLOT]"+nueva_ropa_pk.getSlot() + " " + nueva_ropa_pk.getJugadorId() );

                    em.persist(nueva_ropa);

                    lista.add(nueva_ropa);

                }
            }

for (short i=1; i< 8;i ++) {
    log.debug("[TRAZA][TABLA ROPA PONER2]:" + (Integer)p_tabla.get(i) );
}
            // Iterar Hashtable para meter ropa en el armario
            for ( short p_slot=1;p_slot<=7;p_slot++ )
            {
                Integer ropa_id_poner = (Integer)p_tabla.get(p_slot);

                log.debug("[TRAZA][ROPA PONER]:" + (Integer)p_tabla.get(p_slot));

                // Si está a null o -1 el slot queda invariable ( ni se quita ni se pone ropa)
                if ( ropa_id_poner != null &&
//                     ropa_id_poner != 0    &&
                     ropa_id_poner != -1) {

                    log.debug("[TRAZA][ITERANDO ROPA_JUGADOR]:" + p_slot );
                    if ( lista.get(p_slot-1).getRopa()!=null  ) {
                        RopaJugador r_ropajugador = lista.get(p_slot-1);
                        int ropa_id_quitar   = r_ropajugador.getRopa().getId();
                        int instancia_quitar = r_ropajugador.getRopaInstanciaId()== null ? 0 : r_ropajugador.getRopaInstanciaId() ;
                        int instancia_poner  = 0;
                        if ( ropa_id_poner <-1) {
                            instancia_poner  = ropa_id_poner*-1;
                            if ( instancia_poner == instancia_quitar )
                                ropa_id_poner = ropa_id_quitar;
                        }
log.debug("[TRAZA][REVISAR QUITAR SLOT]:" + p_slot + " id_quitar " + ropa_id_quitar + " id_poner " + ropa_id_poner
        + " instacia_quitar " + instancia_quitar
        + " instacia_poner " + instancia_poner
        );
                        /* Si la ropa a quitar es la misma ropa que vamos a poner de nuevas dejamos el slot tal cual */
                        if ( ropa_id_quitar   != ropa_id_poner ||
                             instancia_quitar != instancia_poner  ) {
log.debug("[TRAZA][QUITAR ROPA VIEJA DEL SLOT]:" + ropa_id_quitar + " id" + ropa_id_poner);

                            /* Buscamos la ropa */
                            Query q4 = em.createNamedQuery("Ropa.findById");
                            q4.setParameter("id", ropa_id_quitar);
                            List<Ropa> lista_ropa = q4.getResultList();
                            if (lista_ropa.isEmpty())
                                throw new ExcepcionGeneral( -3, "Ropa a quitar no Existe"  );

                            Ropa ropa_quitar = lista_ropa.get(0);

                            // 2011-11-22 Ropa Durable
                            if ( ropa_quitar.getUsos()>=0 && ropa_quitar.getUsos() != r_ropajugador.getUsos() ) {
                                guardar_armario = false;
                            }

                            if ( ropa_quitar.getCategoria().getId() == 2000 ) // Tatuaje
                            {
                                if ( p_tipo_operacion == 0) {
                                    // Operación vestir/desvestir normal
                                    throw new ExcepcionGeneral( -15, "El tatuaje se quita con una carta"  );
                                }

                                if ( p_tipo_operacion == 2 )
                                {
                                    // Vender Jugador desde inventario
                                    // El tatuaje se pierde
                                    guardar_armario = false;
                                    log.debug("[TRAZA][TATUAJE PERDIDO]:" + p_slot + " ropa " + ropa_id_quitar + " ");
                                }
                                if ( p_tipo_operacion == 3) {
                                    // Jugar carta de quitar tatuaje
                                    // NO Guardamos el tatuaje en el armario

                                    // Buscamos carta de quitar tatuaje
                                    /* DatosEquipo de = new DatosEquipo();
                                       CartaEquipo carta_equipo = de.BuscarCartaEquipo(em, jugador.getEquipo().getId(), 10003 ); */

                                    CartaEquipo carta_equipo = Util.BuscarCartaEquipo(em, jugador.getEquipo().getId(), 10003 );

                                    if (carta_equipo == null)
                                        throw new ExcepcionGeneral( -16, "Carta de quitar tatuaje no Existe"  );

                                    Cartas cartas = new Cartas();
                                    cartas.sacarCartaInventario ( em, jugador.getEquipo().getId(), 10003 , 1 );

                                    guardar_armario = false;
                                }
                            }
                            // Guardo la ropa que estaba puesta antes
                            if ( guardar_armario  ) {

                                if ( instancia_quitar!= 0 )
                                    error = liberaInstancia ( em, r_ropajugador );
                                else
                                    error = meterArmario ( em, jugador.getEquipo().getId(), ropa_id_quitar );
                            }
                            // Vacío el slot
                            r_ropajugador.setRopa(null);
                            r_ropajugador.setUsos(0);
                        }
                    }
                }
            }

            // Iterar Hashtable para poner la nueva ropa y sacarla del armario
            for ( short p_slot=1;p_slot<=7;p_slot++ )
            {
                boolean misma_ropa=false;
                Integer ropa_id_poner = (Integer) p_tabla.get(p_slot);

                int instancia_poner = 0;
                if ( ropa_id_poner<-1 )
                    instancia_poner = Math.abs(ropa_id_poner);

                RopaJugador ropa_jugador_poner = lista.get(p_slot-1);

                // Si la ropa a poner en el slot es la misma que está puesta actualmente
                if ( lista.get(p_slot-1).getRopa() !=null &&
                     lista.get(p_slot-1).getRopa().getId().intValue()==ropa_id_poner.intValue() &&
                     // y el slot no tiene instancia y lo que vamos a poner tampoco es una instancia
                     (lista.get(p_slot-1).getRopaInstanciaId() == null && instancia_poner==0) ||
                     // o el slot tiene instancia y es la misma instancia que vamos a poner
                     (lista.get(p_slot-1).getRopaInstanciaId() != null && instancia_poner>0  &&
                      lista.get(p_slot-1).getRopaInstanciaId() == instancia_poner )
                     ) {
                    misma_ropa=true;

                    log.debug("[NO TOCO]"+p_slot+ " ropa" +lista.get(p_slot-1).getRopa() );
                }


                if ( ropa_id_poner != null && 
                     ropa_id_poner != 0    &&
                     ropa_id_poner != -1   &&
                     misma_ropa==false) {
                    // Si ropa_id==0 es que quiero quitar la ropa existente y no poner nada

                    log.debug("[TRAZA][ACTUALIZO SLOT]:" + p_slot);
                    RopaJugador r_ropajugador = lista.get(p_slot-1);

                    RopaInstancia ri = null;
                    if ( instancia_poner > 0 ) {
                        ri = buscarInstancia( em, instancia_poner);
                        if ( ri == null)
                            throw new ExcepcionGeneral( -18, "Instancia no encontrada"  );
                        ropa_id_poner = ri.getRopa().getId();

                        // 21-03-2012 Comprobación de instancia ya en uso.
                        if ( ri.getJugadorId() != null )
                            throw new ExcepcionGeneral( -19, "Instancia en uso"  );

                    }

                    // Asignamos la ropa
                    Query q4 = em.createNamedQuery("Ropa.findById");
                    q4.setParameter("id", ropa_id_poner);
                    List<Ropa> lista_ropa = q4.getResultList();
                    if (lista_ropa.isEmpty())
                        throw new ExcepcionGeneral( -4, "Ropa a poner no Existe"  );

                    Ropa ropa_poner = lista_ropa.get(0);

                    // Comprobar la idoneidad del slot
                    switch ( ropa_poner.getCategoria().getId() ){
                        case 2000: // Tatuaje
                            if ( p_slot != 6 && p_slot != 7)
                                throw new ExcepcionGeneral( -14, "Slot no adecuado"  );
                            break;
                        case 2001: // Zapatillas
                            if ( p_slot != 5)
                                throw new ExcepcionGeneral( -14, "Slot no adecuado"  );
                            break;
                        case 2002: // Muñequeras
                            if ( p_slot != 3 && p_slot != 4)
                                throw new ExcepcionGeneral( -14, "Slot no adecuado"  );
                            break;
                        case 2003: // Brazaletes
                            if ( p_slot != 1 && p_slot != 2)
                                throw new ExcepcionGeneral( -14, "Slot no adecuado"  );
                            break;
                    }

                    r_ropajugador.setRopa( ropa_poner );
                    // 2011-11-22 Ropa Durable
                    // cuando vistes una ropa se asigna el total de usos
                    r_ropajugador.setUsos( ropa_poner.getUsos() );
                    // 2011-11-22 Ropa Durable

                    if ( ri != null ) {
                        // 30-01-2012 Instancias de ropa caducable
                        asignaInstancia ( em, r_ropajugador, jugador, ri );
                        log.debug("[TRAZA][PONER INSTANCIA SLOT]:" + r_ropajugador.getRopaJugadorPK().getSlot() +" - "+
                                r_ropajugador.getRopaJugadorPK().getJugadorId() + " ROPA "+ropa_poner.getId() + " INSTANCIA " + r_ropajugador.getRopaInstanciaId());

                    } else {
                        sacarArmario ( em, jugador.getEquipo().getId(), ropa_poner );
                        log.debug("[TRAZA][PONER ROPA SLOT]:" + r_ropajugador.getRopaJugadorPK().getSlot() +" - "+
                                r_ropajugador.getRopaJugadorPK().getJugadorId() + " ROPA "+ropa_poner.getId());
                    }
                }
            } // Iterar Hashtable

            Vestidor vestidor = new Vestidor();
            error = vestidor.calcularRopaJugador ( em, jugador );

            if ( hacer_commit == true)
                em.getTransaction().commit();

            log.debug("[TRAZA][COMMIT][Vestir]" );
            retorno = "error=0";

            retorno = retorno
+ ";c01="+(jugador.getBT2()             +jugador.getT2          ())
+ ";c02="+(jugador.getBT3()             +jugador.getT3          ())
+ ";c03="+(jugador.getBT1()             +jugador.getT1          ())
+ ";c04="+(jugador.getBAgresividad()    +jugador.getAgresividad ())
+ ";c05="+(jugador.getBDriblin()        +jugador.getDriblin     ())
+ ";c06="+(jugador.getBPase()           +jugador.getPase        ())
+ ";c07="+(jugador.getBReboteAtaque()   +jugador.getReboteAtaque())
+ ";c08="+(jugador.getBDefensa()        +jugador.getDefensa     ())
+ ";c09="+(jugador.getBRobo()           +jugador.getRobo        ())
+ ";c10="+(jugador.getBTapon()          +jugador.getTapon       ())
+ ";c11="+(jugador.getBReboteDefensa()  +jugador.getReboteDefensa())
+ ";c12="+(jugador.getBResistencia()    +jugador.getResistencia ())
+ ";c13="+(jugador.getBVelocidad()      +jugador.getVelocidad   ())
+ ";c14="+(jugador.getBSprint()         +jugador.getSprint      ())
+ ";c15="+(jugador.getBTeamwork()	+jugador.getTeamwork    ())
+ "";

        } catch (ExcepcionGeneral e) {
            log.error("[ERROR][VESTIR1]: " , e);
            retorno = "error="+e.getCodigo()+";descripcion="+e.getDescripion();
            if ( em != null && em.getTransaction().isActive() )
                em.getTransaction().rollback();
        } catch (Exception x) {
            log.error("[ERROR][VESTIR2]: ", x);
            retorno = "error=-100";
            if ( em != null && em.getTransaction().isActive() )
                em.getTransaction().rollback();
        } finally {

            /*try { if (em != null && hacer_commit ) em.close(); } // revisado 09/08/2012
            catch (Exception ex) {
                log.error("[ERROR][constructor]: EMT base de datos: " , ex);
            } */
        }
        return retorno;
    }

    // Libera la instancia de ropa jugador y desasigna el jugador de ropa_instancia
    private int liberaInstancia ( EntityManager em, RopaJugador p_ropa_jugador )
    {
        Query q = em.createNamedQuery("RopaInstancia.findById");
        q.setParameter("id", p_ropa_jugador.getRopaInstanciaId());

        RopaInstancia ri = (RopaInstancia)q.getSingleResult();

        ri.setJugadorId(null);
        em.persist(ri);

        p_ropa_jugador.setRopaInstanciaId(null);
        p_ropa_jugador.setFCaduca(null);

        return 0;
    }

    // Asigna una instancia a ropa jugador y desasigna el jugador de ropa_instancia
    private int asignaInstancia ( EntityManager em, RopaJugador p_ropa_jugador, Jugador p_jugador, RopaInstancia ri )
    {
        ri.setJugadorId( p_jugador);
        em.persist(ri);

        p_ropa_jugador.setRopaInstanciaId( ri.getId() );
        p_ropa_jugador.setFCaduca( ri.getFCaduca() );

        return 0;
    }

    public RopaInstancia buscarInstancia( EntityManager em, int p_clave ) {

        Query q = em.createNamedQuery("RopaInstancia.findById");
        q.setParameter("id", p_clave );

        RopaInstancia ri = (RopaInstancia)q.getSingleResult();

        return ri;
    }
}
